<template>
    <el-popover
        ref="popover"
        :width="width"
        class="tree-popover"
        popper-class="tree-select"
        v-model="visible"
        :placement="placement"
        trigger="click"
        :disabled="disabled"
    >
        <el-tree
            ref="tree"
            :data="treeOptions"
            :props="treeProps"
            node-key="id"
            :show-checkbox="type === 'multi'"
            :default-expand-all="defaultExpandAll"
            :highlight-current="true"
            :expand-on-click-node="false"
            :default-checked-keys="defaultCheckedKeys"
            :filter-node-method="filterNode"
            @current-change="selectChange"
            @check="checkChange"
        />
        <el-select
            :disabled="disabled"
            v-model="value"
            slot="reference"
            filterable
            :filter-method="filterTreeData"
            :popper-append-to-body="false"
            :size="size"
            style="width: 100%"
            :multiple="type === 'multi'"
            @clear="clearValue"
            @remove-tag="removeTag"
            :clearable="clearable"
            :placeholder="placeholder"
        ></el-select>
    </el-popover>
</template>

<script>
export default {
    name: 'treeSelect',
    model: {
        prop: 'selectValue',
        event: 'selectChange'
    },
    props: {
        disabled: {
            type: Boolean,
            default: false
        },
        clearable: {
            type: Boolean,
            default: true
        },
        selectValue: {
            type: [Number, String, Array],
            default: ''
        },
        defaultCheckedKeys: {
            type: Array,
            default: () => []
        },
        type: {
            type: String,
            default: 'single'
        },
        treeOptions: {
            type: Array,
            default: () => []
        },
        size: {
            type: String,
            default: 'small'
        },
        width: {
            type: Number,
            default: 180
        },
        treeProps: {
            type: Object,
            default: () => {
                return {
                    value: 'id',
                    label: 'deptName',
                    children: 'children'
                }
            }
        },
        nodeKey: {
            type: String,
            default: ''
        },
        placeholder: {
            type: String,
            default: '请选择'
        },
        placement: {
            type: String,
            default: 'bottom-start'
        },
        defaultExpandAll: {
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            visible: false,
            // value: '',
            selectObj: []
        }
    },
    watch: {
        // selectValue: {
        //     immediate: true,
        //     handler(newValue, oldValue) {
        //         if (this.type === 'single') {
        //             this.value = this.findLabel(this.treeOptions, newValue)
        //         } else {
        //             //多选
        //             if (newValue.length > 0) {
        //                 this.$refs.tree.setCheckedKeys(newValue)
        //                 this.value = this.findLabelMulti()
        //             } else {
        //                 this.value = ''
        //             }
        //         }
        //     }
        // }
        selectValue: {
            immediate: true,
            handler(newValue, oldValue) {
                if (this.type === 'multi') {
                    if (Object.prototype.toString.call(newValue) === '[object Array]') {
                        this.$refs.tree.setCheckedKeys(newValue)
                    }
                }
            }
        }
    },
    computed: {
        value: {
            get() {
                if (this.type === 'single') {
                    return this.findLabel(this.treeOptions, this.selectValue, '')
                } else {
                    //多选
                    if (this.selectValue.length > 0) {
                        return this.findLabelMulti()
                    } else {
                        return ''
                    }
                }
            },
            set(val) {}
        }
    },
    methods: {
        checkChange() {
            this.$emit('selectChange', this.$refs.tree.getCheckedKeys())
        },
        filterTreeData(val) {
            this.$refs.tree.filter(val)
        },
        findLabelMulti() {
            let labelArr = []
            let obj = []
            let selectNodes = this.$refs.tree.getCheckedNodes()
            for (let i = 0; i < selectNodes.length; i++) {
                let item = selectNodes[i]
                if (item.parentId) {
                    labelArr.push(this.findParentName(item.parentId) + ' / ' + item[this.treeProps.label])
                    obj.push({
                        label: this.findParentName(item.parentId) + ' / ' + item[this.treeProps.label],
                        id: item[this.treeProps.value],
                        parentId: item.parentId
                    })
                } else if (
                    // 没有子级的情况
                    !item.parentId &&
                    (!item[this.treeProps.children] || item[this.treeProps.children].length === 0)
                ) {
                    labelArr.push(item[this.treeProps.label])
                    obj.push({
                        label: item[this.treeProps.label],
                        id: item[this.treeProps.value]
                        // parentId: item.parentId // 有可能是null或者undefined
                    })
                }
            }
            this.selectObj = obj
            return labelArr
        },
        removeTag(tag) {
            let selectValue = []
            for (let j = 0; j < this.selectObj.length; j++) {
                let objItem = this.selectObj[j]
                if (tag === objItem['label']) {
                    selectValue = this.selectValue.filter((item) => {
                        return item !== objItem['id'] && item !== objItem['parentId']
                    })
                }
            }
            this.$emit('selectChange', selectValue)
        },
        findParentName(parentId) {
            for (let i = 0; i < this.treeOptions.length; i++) {
                let item = this.treeOptions[i]
                if (item.id === parentId) {
                    return item[this.treeProps.label]
                }
            }
        },
        findLabel(data, value, str) {
            if (value) {
                for (let i = 0; i < data.length; i++) {
                    let item = data[i]
                    if (item[this.treeProps.value] === this.selectValue) {
                        if (str) {
                            return str + ' / ' + item[this.treeProps.label]
                        } else {
                            return item[this.treeProps.label]
                        }
                    } else if (item[this.treeProps.children] && item[this.treeProps.children].length > 0) {
                        if (str) {
                            let valStr = this.findLabel(
                                item[this.treeProps.children],
                                value,
                                str + ' / ' + item[this.treeProps.label]
                            )
                            if (valStr) {
                                return valStr
                            }
                        } else {
                            let valStr = this.findLabel(
                                item[this.treeProps.children],
                                value,
                                item[this.treeProps.label]
                            )

                            if (valStr) {
                                return valStr
                            }
                        }
                    }
                }
            } else {
                return ''
            }
        },
        clearValue() {
            if (this.type === 'multi') {
                this.$emit('selectChange', [])
            } else if (this.type === 'single') {
                this.$emit('selectChange', '')
            }
            this.$emit('getNodeData', null)
            this.filterTreeData('')
        },
        selectChange(data) {
            this.$emit('selectChange', data[this.treeProps.value])
            this.$emit('getNodeData', data)
            this.visible = false
        },
        filterNode(value, data) {
            if (!value) return true
            return data[this.treeProps.label].indexOf(value) !== -1
        }
    }
}
</script>

<style lang="scss">
.tree-popover .el-select-dropdown {
    display: none;
}
.tree-select {
    width: auto !important;
}
</style>
